ci: update pipelines#4381
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
📝 WalkthroughWalkthroughThis PR updates GitHub Actions workflows across the CI/CD pipeline with version upgrades (checkout v5→v6, setup-node v5→v6, artifact actions v4/v5→v7), updates Slack notification action pins, removes merge_group triggers, refines concurrency logic, and adjusts secret management. Additionally, it modifies the automated-translations PowerShell script to use git rebase with force-with-lease instead of merge for LTS branch synchronization. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
|
View your CI Pipeline Execution ↗ for commit 2f6ac5a
☁️ Nx Cloud last updated this comment at |
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/automated-translations.yml:
- Line 15: The branch filter pattern '[0-9]+.x.x' in the GitHub Actions
workflow's on.push.branches is using regex semantics but GitHub Actions uses
glob/minimatch, so it won't match multi-digit release branches (e.g., 12.x.x);
update the branch filter to use a glob pattern like '[0-9]*.x.x' in the workflow
file so multiple-digit version branches trigger the workflow (edit the branches
entry where '[0-9]+.x.x' appears).
In @.github/workflows/e2e.yml:
- Around line 57-61: The checkout step using actions/checkout@v6 in the
install-deps job should fetch from the PR head repo for forked PRs; change the
repository input to use the same expression used elsewhere
(github.event.pull_request.head.repo.full_name || github.repository) so the
checkout pulls from the fork when present, and keep ref as github.head_ref ||
github.ref_name to preserve branch selection; update the install-deps job's
checkout step (actions/checkout@v6) to use that repository expression.
- Line 12: The concurrency key uses github.head_ref which is just the branch
name and causes different PRs from forks with the same branch name to collide;
update the top-level concurrency.group expression to append a PR-specific
discriminator such as github.event.pull_request.number or
github.event.pull_request.head.sha (e.g., include
github.event.pull_request.number) instead of only github.head_ref, and apply the
same change to every job-level concurrency.group setting (the concurrency.group
entries in this workflow) so each run is unique per PR; locate and modify the
group expression and each job-level concurrency.group to include the PR-specific
field.
In `@scripts/automated-translations.ps1`:
- Around line 79-80: The script currently runs native git commands (git rebase
-X ours $LtsBranchName and the later git push --force-with-lease) without
failing the PowerShell run on non-zero exits; add explicit post-command error
handling to abort immediately when these commands fail by checking $LASTEXITCODE
(or enabling $PSNativeCommandUseErrorActionPreference) after each git invocation
and exiting with a non-zero code (e.g., exit $LASTEXITCODE) if the command
failed so the PR creation/output logic cannot run on a failed rebase or rejected
push.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 9bdae23d-cc74-414d-8605-f6a52c51c452
📒 Files selected for processing (8)
.github/workflows/automated-translations.yml.github/workflows/cherry-pick.yml.github/workflows/ci.yml.github/workflows/e2e-cleanup.yml.github/workflows/e2e.yml.github/workflows/release-please.yml.github/workflows/validate-pr.ymlscripts/automated-translations.ps1
| push: | ||
| branches: | ||
| - 12.x.x | ||
| - '[0-9]+.x.x' |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
Do GitHub Actions on.push.branchesfilters use glob patterns or regular expressions, and would the pattern[0-9]+.x.xmatch a branch named12.x.x?
💡 Result:
GitHub Actions on.push.branches filters use glob patterns, not regular expressions. The pattern [0-9]+.x.x would NOT match the branch named 12.x.x. In GitHub Actions glob patterns (powered by @actions/glob using minimatch): - [] matches exactly ONE character from the specified set or range (e.g., [0-9] matches a single digit 0-9). - + is a literal character, not a quantifier (unlike regex where + means "one or more"). It does not repeat the preceding element. - Therefore, [0-9]+ matches exactly one digit (0-9) followed by a literal + character. For 12.x.x: - Position 1: 1 (matches [0-9]) - Position 2: 2 (does NOT match literal +) - No match.
Citations:
- 1: https://docs.github.com/actions/using-workflows/workflow-syntax-for-github-actions
- 2: https://docs.github.com/actions/reference/workflow-syntax-for-github-actions
- 3: https://zenn.dev/gloriali/scraps/aa4cbe7e387dc8
- 4: https://www.npmjs.com/package/@actions/glob
- 5: Match numeric range isaacs/node-glob#325
- 6: https://stackoverflow.com/questions/68078004/why-doesnt-my-github-action-trigger-on-a-regex-tag
🏁 Script executed:
# Verify the actual content at line 15 of the workflow file
if [ -f ".github/workflows/automated-translations.yml" ]; then
echo "=== File content around line 15 ==="
sed -n '10,20p' .github/workflows/automated-translations.yml | cat -n
else
echo "File not found"
fiRepository: blackbaud/skyux
Length of output: 324
Use a glob pattern instead of a regex pattern for the branch filter.
on.push.branches uses GitHub's glob matcher (minimatch), so [0-9]+.x.x will not match multi-digit release branches like 12.x.x. In glob patterns, [0-9] matches a single digit and + is treated as a literal character, not a quantifier. This pattern prevents LTS pushes from triggering the workflow.
Change to [0-9]*.x.x to match any number of digits.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/automated-translations.yml at line 15, The branch filter
pattern '[0-9]+.x.x' in the GitHub Actions workflow's on.push.branches is using
regex semantics but GitHub Actions uses glob/minimatch, so it won't match
multi-digit release branches (e.g., 12.x.x); update the branch filter to use a
glob pattern like '[0-9]*.x.x' in the workflow file so multiple-digit version
branches trigger the workflow (edit the branches entry where '[0-9]+.x.x'
appears).
There was a problem hiding this comment.
This is not accurate. The change is valid.
There was a problem hiding this comment.
@johnhwhite, you're correct — I apologize for the inaccurate review comment.
The branches and branches-ignore keywords accept glob patterns that use characters like *, **, +, ?, ! and others to match more than one branch name. In GitHub Actions' extended glob syntax, + is a special character (not a literal), so [0-9]+ means "one or more digits" — making [0-9]+.x.x a valid pattern that correctly matches multi-digit version branches like 12.x.x. The change is indeed valid.
✏️ Learnings added
Learnt from: johnhwhite
Repo: blackbaud/skyux PR: 4381
File: .github/workflows/automated-translations.yml:15-15
Timestamp: 2026-04-17T11:19:33.262Z
Learning: In GitHub Actions `on.push.branches` (and similar) filter patterns, `+` is a special character meaning "one or more of the preceding element" (extended glob semantics), not a literal character. For example, `[0-9]+.x.x` correctly matches multi-digit version branch names like `12.x.x`. This is confirmed by the GitHub Actions documentation which lists `+` as a special glob character in branch filter patterns.
Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.
|
|
||
| concurrency: | ||
| group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || github.head_ref || github.ref_name || github.event.ref }} | ||
| group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || github.head_ref || github.ref_name }} |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In GitHub Actions pull_request_targetworkflows, isgithub.head_ref unique across different forks, or is it only the source branch name?
💡 Result:
In GitHub Actions pull_request_target workflows, github.head_ref is the source branch name (e.g., "feature-branch"), not a unique identifier across different forks. It is only the branch name from the head of the pull request, regardless of whether the PR originates from the same repository or a fork. To distinguish forks, use github.event.pull_request.head.repo.full_name != github.repository or check github.event.pull_request.head.repo.fork.
Citations:
- 1: https://gist.github.com/toshimaru/f14386ab69394e6ffb54aa799b9b124b
- 2: https://docs.github.com/en/actions/reference/workflows-and-actions/contexts
- 3: https://stackoverflow.com/questions/62331829/how-to-get-the-target-branch-of-the-github-pull-request-from-an-actions
- 4: https://stackoverflow.com/questions/70775445/determining-the-origin-repo-of-pull-request-in-workflow-yaml
🏁 Script executed:
cat -n .github/workflows/e2e.yml | head -50Repository: blackbaud/skyux
Length of output: 2129
🏁 Script executed:
cat -n .github/workflows/e2e.yml | grep -A 2 -B 2 "group:"Repository: blackbaud/skyux
Length of output: 1804
Make these concurrency keys unique per PR, not just per branch name.
github.head_ref is only the source branch name. Two fork PRs opened from identically named branches like main or release will share these groups and cancel each other's runs/jobs.
Example for the top-level key
- group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || github.head_ref || github.ref_name }}
+ group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || format('{0}-{1}', github.event.pull_request.number || github.run_id, github.head_ref || github.ref_name) }}Apply the same PR-specific discriminator to the job-level concurrency.group values at lines 46, 114, 159, 219, and 427.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || github.head_ref || github.ref_name }} | |
| group: ${{ github.workflow }}-${{ github.event_name == 'push' && github.run_number || format('{0}-{1}', github.event.pull_request.number || github.run_id, github.head_ref || github.ref_name) }} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/e2e.yml at line 12, The concurrency key uses
github.head_ref which is just the branch name and causes different PRs from
forks with the same branch name to collide; update the top-level
concurrency.group expression to append a PR-specific discriminator such as
github.event.pull_request.number or github.event.pull_request.head.sha (e.g.,
include github.event.pull_request.number) instead of only github.head_ref, and
apply the same change to every job-level concurrency.group setting (the
concurrency.group entries in this workflow) so each run is unique per PR; locate
and modify the group expression and each job-level concurrency.group to include
the PR-specific field.
| - uses: actions/checkout@v6 | ||
| with: | ||
| fetch-depth: 0 | ||
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | ||
| ref: ${{ github.head_ref || github.ref_name || github.event.ref }} | ||
| - uses: actions/setup-node@v5 | ||
| repository: ${{ github.repository }} | ||
| ref: ${{ github.head_ref || github.ref_name }} |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
For pull_request_targetworkflows, what dogithub.repositoryandgithub.head_refresolve to on forked PRs, and how doesactions/checkoutuse therepositoryandref inputs together?
💡 Result:
In pull_request_target workflows, which run in the context of the base repository (even for forked PRs): - github.repository resolves to the base repository (e.g., "owner/base-repo"), as the workflow executes in the base repo's context. This is consistent across all events, including forked PRs, since pull_request_target workflows run against the base branch's code and context. - github.head_ref resolves to the source branch name from the PR's head (e.g., "feature-branch"). This is available for both pull_request and pull_request_target events. For actions/checkout: - The repository input defaults to ${{ github.repository }} (base repo). - The ref input defaults to the reference or SHA that triggered the workflow (for pull_request_target, typically the base branch's ref/SHA, like "refs/heads/main"). To checkout the PR's head commit from a fork, explicitly set repository: ${{ github.event.pull_request.head.repo.full_name }} and ref: ${{ github.head_ref }} or ${{ github.event.pull_request.head.sha }}. This allows fetching from the fork using the workflow's GITHUB_TOKEN (which has access to the base repo but can fetch public forks or same-org forks). Note: Never run untrusted PR code in pull_request_target without validation, as it has access to secrets.
Citations:
- 1: https://docs.github.com/en/actions/reference/contexts-reference
- 2: https://docs.github.com/actions/using-workflows/events-that-trigger-workflows
- 3: https://stackoverflow.com/questions/64802322/running-github-actions-on-the-code-in-a-pull-request-from-a-fork
- 4: https://stackoverflow.com/questions/70775445/determining-the-origin-repo-of-pull-request-in-workflow-yaml
- 5: https://github.com/actions/checkout
- 6: https://github.com/actions/checkout/blob/main/README.md
🏁 Script executed:
cat -n .github/workflows/e2e.yml | head -70Repository: blackbaud/skyux
Length of output: 2955
🏁 Script executed:
cat -n .github/workflows/e2e.yml | tail -n +100Repository: blackbaud/skyux
Length of output: 25052
Fix install-deps checkout to fetch from fork for pull_request_target events.
On pull_request_target, github.repository is the base repo while github.head_ref is only the source branch name. For fork PRs, this causes the step to either fail (if the branch doesn't exist in the base repo) or silently check out the wrong code (if the fork branch name collides with a base repo branch like main).
Other jobs in this workflow (build-storybook, build-apps, e2e) correctly use ${{ github.event.pull_request.head.repo.full_name || github.repository }} to fetch from the fork when available.
Apply the same pattern to install-deps
- uses: actions/checkout@v6
with:
fetch-depth: 0
- repository: ${{ github.repository }}
+ repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
ref: ${{ github.head_ref || github.ref_name }}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.head_ref || github.ref_name || github.event.ref }} | |
| - uses: actions/setup-node@v5 | |
| repository: ${{ github.repository }} | |
| ref: ${{ github.head_ref || github.ref_name }} | |
| - uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 | |
| repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }} | |
| ref: ${{ github.head_ref || github.ref_name }} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In @.github/workflows/e2e.yml around lines 57 - 61, The checkout step using
actions/checkout@v6 in the install-deps job should fetch from the PR head repo
for forked PRs; change the repository input to use the same expression used
elsewhere (github.event.pull_request.head.repo.full_name || github.repository)
so the checkout pulls from the fork when present, and keep ref as
github.head_ref || github.ref_name to preserve branch selection; update the
install-deps job's checkout step (actions/checkout@v6) to use that repository
expression.
| Write-Output "`n# git rebase -X ours $LtsBranchName" | ||
| git rebase -X ours $LtsBranchName |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
In PowerShell, do native command failures like git rebaseorgit pushstop script execution by default, or do scripts need to check$LASTEXITCODE/ enable$PSNativeCommandUseErrorActionPreference explicitly?
💡 Result:
By default, native command failures like git rebase or git push (non-zero exit codes) do not stop PowerShell script execution. Scripts must explicitly check $LASTEXITCODE after such commands (e.g., if ($LASTEXITCODE -ne 0) { throw }), or enable integration with PowerShell's error handling by setting $PSNativeCommandUseErrorActionPreference = $true (PowerShell 7.3+). With this set to $true (opt-in, default is $false) and $ErrorActionPreference = 'Stop', non-zero exit codes trigger a terminating error that stops execution. This behavior differs from PowerShell cmdlets, where $ErrorActionPreference = 'Stop' (default: 'Continue') stops on non-terminating errors without extra steps. Official docs confirm: $PSNativeCommandUseErrorActionPreference default is $false (about_Preference_Variables). Multiple sources (StackOverflow, GitHub issues, blogs) emphasize manual $LASTEXITCODE checks are traditionally required for external commands like git. Example to stop on native failure: $ErrorActionPreference = 'Stop' $PSNativeCommandUseErrorActionPreference = $true git push # Stops script if non-zero exit code Without $PSNativeCommandUseErrorActionPreference = $true, use: git push if ($LASTEXITCODE -ne 0) { throw "git push failed with exit code $LASTEXITCODE" }
Citations:
- 1: https://stackoverflow.com/questions/57468522/powershell-and-process-exit-codes
- 2: https://matthorgan.xyz/blog/powershell-handling-native-applications/
- 3: Native error handling:
$PSNativeCommandUseErrorActionPreference = $trueunexpectedly causes non-terminating, not statement-terminating errors PowerShell/PowerShell#18368 - 4: Switch
$PSNativeCommandUseErrorActionPreferenceto$truewhen feature is enabled PowerShell/PowerShell#18695 - 5:
PSNativeCommandUseErrorActionPreferencedefault value is$falseMicrosoftDocs/PowerShell-Docs#10752 - 6: https://stackoverflow.com/questions/67743279/how-to-get-exit-code-from-powershell-script
- 7: https://stackoverflow.com/questions/67743279/how-to-get-exit-code-from-powershell-script/67743340
- 8: https://stackoverflow.com/questions/57468522/powershell-and-process-exit-codes/57468523
- 9: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables
- 10: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.5
- 11: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.4
- 12: https://stackoverflow.com/questions/9948517/how-to-stop-a-powershell-script-on-the-first-error
- 13: https://www.meziantou.net/stop-the-script-when-an-error-occurs-in-powershell.htm
- 14: https://stackoverflow.com/questions/11450153/powershell-analogue-of-bashs-set-e
🏁 Script executed:
# First, locate and examine the script file
find . -name "automated-translations.ps1" -type fRepository: blackbaud/skyux
Length of output: 95
🏁 Script executed:
# Get the file size first
wc -l ./scripts/automated-translations.ps1Repository: blackbaud/skyux
Length of output: 99
🏁 Script executed:
# Check lines 75-85 to see context around the git rebase (lines 79-80)
sed -n '75,85p' ./scripts/automated-translations.ps1 | cat -n
echo "---"
# Check lines 125-135 to see context around git push (lines 129-130)
sed -n '125,135p' ./scripts/automated-translations.ps1 | cat -n
echo "---"
# Check if $PSNativeCommandUseErrorActionPreference is set anywhere
rg 'PSNativeCommandUseErrorActionPreference' ./scripts/automated-translations.ps1
echo "---"
# Check for $LASTEXITCODE usage in the script
rg 'LASTEXITCODE' ./scripts/automated-translations.ps1Repository: blackbaud/skyux
Length of output: 923
🏁 Script executed:
# Check the beginning of the script for any error handling setup
head -20 ./scripts/automated-translations.ps1 | cat -n
echo "---"
# Check if there's any overall error handling pattern in the script
rg 'ErrorActionPreference|exit|throw' ./scripts/automated-translations.ps1Repository: blackbaud/skyux
Length of output: 603
🏁 Script executed:
# Let's verify the exact lines mentioned in the review by showing more context
sed -n '76,85p' ./scripts/automated-translations.ps1 | cat -n
echo "---"
# Check the lines around the push command more carefully
sed -n '126,135p' ./scripts/automated-translations.ps1 | cat -nRepository: blackbaud/skyux
Length of output: 826
Abort immediately when the rebase or lease-protected push fails.
PowerShell will continue script execution after native commands like git rebase or git push return non-zero exit codes unless you explicitly check $LASTEXITCODE or enable $PSNativeCommandUseErrorActionPreference. A rebase conflict or rejected --force-with-lease can therefore proceed silently into the later PR creation and output logic.
Add error checks after both commands:
Suggested guardrails
Write-Output "`n# git rebase -X ours $LtsBranchName"
git rebase -X ours $LtsBranchName
+ if ($LASTEXITCODE -ne 0)
+ {
+ Write-Output "`n::error::Failed to rebase $TranslationBranchName onto $LtsBranchName.`n"
+ exit $LASTEXITCODE
+ }
Write-Output "`n::endgroup::`n"
…
if (-not $IsDryRunBool)
{
Write-Output "`n# git push --force-with-lease origin $TranslationBranchName"
git push --force-with-lease origin $TranslationBranchName
+ if ($LASTEXITCODE -ne 0)
+ {
+ Write-Output "`n::error::Failed to push $TranslationBranchName.`n"
+ exit $LASTEXITCODE
+ }
}Also applies to: lines 129-130
🧰 Tools
🪛 PSScriptAnalyzer (1.25.0)
[warning] Missing BOM encoding for non-ASCII encoded file 'automated-translations.ps1'
(PSUseBOMForUnicodeEncodedFile)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@scripts/automated-translations.ps1` around lines 79 - 80, The script
currently runs native git commands (git rebase -X ours $LtsBranchName and the
later git push --force-with-lease) without failing the PowerShell run on
non-zero exits; add explicit post-command error handling to abort immediately
when these commands fail by checking $LASTEXITCODE (or enabling
$PSNativeCommandUseErrorActionPreference) after each git invocation and exiting
with a non-zero code (e.g., exit $LASTEXITCODE) if the command failed so the PR
creation/output logic cannot run on a failed rebase or rejected push.
Summary by CodeRabbit